{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```markdown\n",
    "Copyright 2018-2019 IBM Corp. All Rights Reserved.\n",
    "\n",
    "Licensed under the Apache License, Version 2.0 (the \"License\");\n",
    "you may not use this file except in compliance with the License.\n",
    "You may obtain a copy of the License at\n",
    "\n",
    "    http://www.apache.org/licenses/LICENSE-2.0\n",
    "\n",
    "Unless required by applicable law or agreed to in writing, software\n",
    "distributed under the License is distributed on an \"AS IS\" BASIS,\n",
    "WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
    "See the License for the specific language governing permissions and\n",
    "limitations under the License.\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# MAX Question Answering Demo\n",
    "\n",
    "This notebook will demonstrate how to make a request to the MAX Question Answering model API and how to use the response object received. By default, the notebook uses the [hosted demo instance](http://max-question-answering.max.us-south.containers.appdomain.cloud), but you can use a locally running instance as well by following the instructions on the main README. This notebook can be found on the Model Asset Exchange [GitHub repo](https://github.com/IBM/MAX-Question-Answering/tree/master/) under the `samples/` directory and assumes the same folder [structure](https://github.com/IBM/MAX-Question-Answering/tree/master/samples) is maintained. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests \n",
    "import json\n",
    "import pprint"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "pp = pprint.PrettyPrinter()\n",
    "\n",
    "url = 'http://max-question-answering.max.us-south.containers.appdomain.cloud/model/predict'\n",
    "\n",
    "# To run the model locally uncomment the line below after setting up the local Docker container\n",
    "# url = 'http://localhost:5000/model/predict'\n",
    "\n",
    "def predict(input_file):\n",
    "    with open(input_file, 'rb') as file:\n",
    "        json_data = json.load(file)\n",
    "        r = requests.post(url=url, json=json_data).json()\n",
    "    \n",
    "        return r"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Run inference on a sample file"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Preview the File\n",
    "\n",
    "We first preview the file to see the paragraph and the questions.\n",
    "The input JSON field `paragraphs` contains a list of `paragraph` dictionaries. Each `paragraph` dictionary has a `context` field and a list of `questions`. The `context` is the body of the paragraph and the `questions` are based on this context/body."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'paragraphs': [{'context': 'Super Bowl 50 was an American football game to '\n",
      "                            'determine the champion of the National Football '\n",
      "                            'League (NFL) for the 2015 season. The American '\n",
      "                            'Football Conference (AFC) champion Denver Broncos '\n",
      "                            'defeated the National Football Conference (NFC) '\n",
      "                            'champion Carolina Panthers 24–10 to earn their '\n",
      "                            'third Super Bowl title. The game was played on '\n",
      "                            \"February 7, 2016, at Levi's Stadium in the San \"\n",
      "                            'Francisco Bay Area at Santa Clara, California. As '\n",
      "                            'this was the 50th Super Bowl, the league '\n",
      "                            'emphasized the \"golden anniversary\" with various '\n",
      "                            'gold-themed initiatives, as well as temporarily '\n",
      "                            'suspending the tradition of naming each Super '\n",
      "                            'Bowl game with Roman numerals (under which the '\n",
      "                            'game would have been known as \"Super Bowl L\"), so '\n",
      "                            'that the logo could prominently feature the '\n",
      "                            'Arabic numerals 50.',\n",
      "                 'questions': ['Which NFL team represented the AFC at Super '\n",
      "                               'Bowl 50?',\n",
      "                               'Which NFL team represented the NFC at Super '\n",
      "                               'Bowl 50?',\n",
      "                               'Where did Super Bowl 50 take place?',\n",
      "                               'Which NFL team won Super Bowl 50?',\n",
      "                               'What color was used to emphasize the 50th '\n",
      "                               'anniversary of the Super Bowl?',\n",
      "                               'What was the theme of Super Bowl 50?',\n",
      "                               'What day was the game played on?',\n",
      "                               'What is the AFC short for?']}]}\n"
     ]
    }
   ],
   "source": [
    "json_path = 'small-dev.json'\n",
    "with open(json_path) as f:\n",
    "    input_to_model = json.load(f)\n",
    "pp.pprint(input_to_model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('Super Bowl 50 was an American football game to determine the champion of the '\n",
      " 'National Football League (NFL) for the 2015 season. The American Football '\n",
      " 'Conference (AFC) champion Denver Broncos defeated the National Football '\n",
      " 'Conference (NFC) champion Carolina Panthers 24–10 to earn their third Super '\n",
      " \"Bowl title. The game was played on February 7, 2016, at Levi's Stadium in \"\n",
      " 'the San Francisco Bay Area at Santa Clara, California. As this was the 50th '\n",
      " 'Super Bowl, the league emphasized the \"golden anniversary\" with various '\n",
      " 'gold-themed initiatives, as well as temporarily suspending the tradition of '\n",
      " 'naming each Super Bowl game with Roman numerals (under which the game would '\n",
      " 'have been known as \"Super Bowl L\"), so that the logo could prominently '\n",
      " 'feature the Arabic numerals 50.')\n"
     ]
    }
   ],
   "source": [
    "# Preview paragraph\n",
    "pp.pprint(input_to_model['paragraphs'][0]['context'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Which NFL team represented the AFC at Super Bowl 50?\n",
      "Which NFL team represented the NFC at Super Bowl 50?\n",
      "Where did Super Bowl 50 take place?\n",
      "Which NFL team won Super Bowl 50?\n",
      "What color was used to emphasize the 50th anniversary of the Super Bowl?\n",
      "What was the theme of Super Bowl 50?\n",
      "What day was the game played on?\n",
      "What is the AFC short for?\n"
     ]
    }
   ],
   "source": [
    "# Preview questions\n",
    "for q in input_to_model['paragraphs'][0]['questions']:\n",
    "    print(q)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Run Inference\n",
    "\n",
    "We now pass the file to the MAX model via the predict function defined earlier and print out the answers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'predictions': [['Denver Broncos',\n",
      "                  'Carolina Panthers',\n",
      "                  \"Levi's Stadium in the San Francisco Bay Area at Santa \"\n",
      "                  'Clara, California',\n",
      "                  'Denver Broncos',\n",
      "                  'gold',\n",
      "                  'golden anniversary\"',\n",
      "                  'February 7, 2016',\n",
      "                  'American Football Conference']],\n",
      " 'status': 'ok'}\n"
     ]
    }
   ],
   "source": [
    "answers = predict('small-dev.json')\n",
    "pp.pprint(answers)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Run inference on in-memory data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, say you wanted to pass in your own data, you can do so by directly sending in a POST request."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "info = \"The choice among algorithm categories can partially be made based on the user persona's ability to intervene at different parts of a machine learning pipeline.  If the user is allowed to modify the training data, then pre-processing can be used.  If the user is allowed to change the learning algorithm, then in-processing can be used.  If the user can only treat the learned model as a black box without any ability to modify the training data or learning algorithm, then only post-processing can be used.  AIF360 recommends the earliest mediation category in the pipeline that the user has permission to apply because it gives the most flexibility and opportunity to correct bias as much as possible. If possible, all algorithms from all permissible categories should be tested because the ultimate performance depends on dataset characteristics: there is no one best algorithm independent of dataset.\"\n",
    "data ={\n",
    "   \"paragraphs\":[\n",
    "      {\n",
    "         \"context\":info,\n",
    "         \"questions\":[\n",
    "            \"When can preprocessing be used?\"\n",
    "            ]\n",
    "      }\n",
    "   ]\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'predictions': [['If the user is allowed to modify the training data']],\n",
      " 'status': 'ok'}\n"
     ]
    }
   ],
   "source": [
    "answers = requests.post(url=url, json=data)\n",
    "pp.pprint(answers.json())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can also write the above in-memory data to disc in the same JSON format and then run inference similar to the first use case. We can do that by first saving the object to disc and then calling the `predict` function. _Note_: The file would need to be in the same JSON format as `../samples/small-dev.json`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_path = \"example-data.json\"\n",
    "with open(data_path, \"w\") as f:\n",
    "    json.dump(data, f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'predictions': [['If the user is allowed to modify the training data']],\n",
      " 'status': 'ok'}\n"
     ]
    }
   ],
   "source": [
    "answers = predict('example-data.json')\n",
    "pp.pprint(answers)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
